package com.csii.ssm.aspect;

import com.csii.ssm.common.Dict;
import com.csii.ssm.dto.ResubmitTokenManager;
import com.csii.ssm.exception.AccessRuntimeException;
import com.csii.ssm.exception.AccessRuntimeExceptionDict;
import com.csii.ssm.model.Pjnl;
import com.csii.ssm.model.User;
import com.csii.ssm.service.IPjnlService;
import com.csii.ssm.util.JsonUtil;
import com.csii.ssm.util.SpringContextUtil;
import org.aspectj.lang.JoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Charis on 2016/8/23.
 */
@Component("pjnlAspect")
@Scope("singleton")
public class PjnlAspect {

    private static final Logger logger = LoggerFactory.getLogger(PjnlAspect.class);
    private static final String PATHWITHINHANDLERMAPPING = "org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping";

    @Inject
    private IPjnlService pjnlService;


    @Inject
    public ResubmitTokenManager resubmitTokenManager;

    /**
     * 切面前置  一定执行
     *
     * @param joinPoint
     * @throws Throwable
     */
    public void before(JoinPoint joinPoint) throws Throwable {
        try{
            ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = attr.getRequest();
            HttpSession session = attr.getRequest().getSession();
            String transcodepath = (String) request.getAttribute(PATHWITHINHANDLERMAPPING);
            String transcode = transcodepath.substring(1, transcodepath.length());

            logger.debug("pjnlAspect @Before：===" + transcode + "=== 交易");
            User user = (User) session.getAttribute(Dict.LOGINUSER);
            if (user == null) {
                throw new AccessRuntimeException(AccessRuntimeExceptionDict.ERROR_USER_SESSION_INVALID);
            }
            //校验每一个post请求的token
            resubmitTokenManager.verifyToken(session, (String) joinPoint.getArgs()[0]);
            //校验结束

            Map params = new HashMap();
            params.put(Dict.TRANSCODE, transcode);
            Pjnl pjnl = pjnlService.addPjnl(user, params);
            session.setAttribute(Dict.CURPJNL_ID, pjnl.getId());

            /*logger.debug("@Before：模拟权限检查...");
            logger.debug("@Before：目标方法为：" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
            logger.debug("@Before：参数为：" + Arrays.toString(joinPoint.getArgs()));
            logger.debug("@Before：被织入的目标对象为：" + joinPoint.getTarget());*/
        }catch (AccessRuntimeException e){
            throw new AccessRuntimeException(e.getCause().getMessage());
        }
    }

    /**
     * 切面后置  一定执行  暂时不用,用AfterReturn代替
     *
     * @param joinPoint
     * @throws Throwable
     */
    public void after(JoinPoint joinPoint) throws Throwable {
        try{
            ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = attr.getRequest();
            HttpSession session = attr.getRequest().getSession();
            String transcodepath = (String) request.getAttribute(PATHWITHINHANDLERMAPPING);
            String transcode = transcodepath.substring(1, transcodepath.length());

            logger.debug("pjnlAspect @After：===" + transcode + "=== 交易");
            User user = (User) session.getAttribute(Dict.LOGINUSER);
            if (user == null) {
                throw new AccessRuntimeException(AccessRuntimeExceptionDict.ERROR_USER_SESSION_INVALID);
            }
            Map params = new HashMap();
            //测试 start
            params.put(Dict.TRANSCODE, transcode);
            params.put(Dict.RETCODE, Dict.RET_SUCCESS);
            params.put(Dict.RETMSG, Dict.RET_SUCCESS_MSG);
            params.put(Dict.ID, session.getAttribute(Dict.CURPJNL_ID));
            params.put(Dict.PJNL_STATUS, Dict.JNL_STATUS_OK);
            params.put(Dict.MEMO, "");
            //end

            // pjnlService.updatePjnl(user,params);
        }catch (AccessRuntimeException e){
            throw new AccessRuntimeException(e.getCause().getMessage());
        }
    }


    /**
     * 切面后置  异常处理  有异常执行
     *
     * @param joinPoint
     * @param e
     * @throws Throwable
     */
    public void afterThrowing(JoinPoint joinPoint, Exception e) throws Throwable {
        try{
            ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = attr.getRequest();
            HttpSession session = attr.getRequest().getSession();
            String transcodepath = (String) request.getAttribute(PATHWITHINHANDLERMAPPING);
            String transcode = transcodepath.substring(1, transcodepath.length());

            logger.debug("pjnlAspect @AfterThrowing：===" + transcode + "=== 交易:异常情况");
            User user = (User) session.getAttribute(Dict.LOGINUSER);
            if (user == null) {
                throw new AccessRuntimeException(AccessRuntimeExceptionDict.ERROR_USER_SESSION_INVALID);
            }
            Map params = new HashMap();
            //测试 start
            params.put(Dict.TRANSCODE, transcode);
            String retCode = e.getMessage();
            params.put(Dict.RETCODE, retCode);
            params.put(Dict.RETMSG, SpringContextUtil.getMessage(retCode)); //异常对于的中文解释
            params.put(Dict.ID, session.getAttribute(Dict.CURPJNL_ID));
            params.put(Dict.PJNL_STATUS, Dict.JNL_STATUS_ERROR);
            params.put(Dict.MEMO, "");
            //end
            logger.debug("pjnlAspect Exception：{},{}", retCode, SpringContextUtil.getMessage(retCode));
            pjnlService.updatePjnl(user, params);
        }catch (AccessRuntimeException e2){
            throw new AccessRuntimeException(e2.getCause().getMessage());
        }
    }


    /**
     * 切面后置  返回增强   有无返回值均执行
     *
     * @param joinPoint
     * @param retObj
     * @throws Throwable
     */

    public void afterReturn(JoinPoint joinPoint, Object retObj) throws Throwable {
        try{
            ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = attr.getRequest();
            HttpSession session = attr.getRequest().getSession();
            String transcodepath = (String) request.getAttribute(PATHWITHINHANDLERMAPPING);
            String transcode = transcodepath.substring(1, transcodepath.length());

            logger.debug("pjnlAspect @AfterReturn：===" + transcode + "=== 交易");
            User user = (User) session.getAttribute(Dict.LOGINUSER);
            if (user == null) {
                throw new AccessRuntimeException(AccessRuntimeExceptionDict.ERROR_USER_SESSION_INVALID);
            }
            Map params = new HashMap();
            //测试 start
            params.put(Dict.TRANSCODE, transcode);
            params.put(Dict.RETCODE, Dict.RET_SUCCESS);
            params.put(Dict.RETMSG, Dict.RET_SUCCESS_MSG);
            params.put(Dict.ID, session.getAttribute(Dict.CURPJNL_ID));
            params.put(Dict.PJNL_STATUS, Dict.JNL_STATUS_OK);
            params.put(Dict.MEMO, "");
            //end

            logger.debug(" pjnlAspect ReturnData：{}", JsonUtil.obj2json(retObj));
            pjnlService.updatePjnl(user, params);
        }catch (AccessRuntimeException e){
            throw new AccessRuntimeException(e.getCause().getMessage());
        }
    }
}
